package doudou5G.util;

import doudou5G.pojo.*;
import doudou5G.service.CallService;
import doudou5G.service.NetService;
import doudou5G.service.SendService;
import doudou5G.test.Start;

import java.io.*;
import java.util.*;

public class CardUtil {
    static Map<String, MobileCard> cards= new HashMap<>();
    static Map<String, List<ConsumInfo>> map2= new HashMap<>();
    public static String nowPhone;
    static String nowPassword;
    static MobileCard mobileCard;
    static Scanner sc = new Scanner(System.in);
    static CallServiceImpl csi = new CallServiceImpl();
    static NetServiceImpl nsi = new NetServiceImpl();
    static SendServiceImpl ssi = new SendServiceImpl();
    static{
        List<ConsumInfo> list= new ArrayList<>();
        List<ConsumInfo> list2= new ArrayList<>();
        List<ConsumInfo> list3= new ArrayList<>();
        String phone1 = "13978978956";
        String phone2 = "13954697751";
        String phone3 = "13955687997";
        MobileCard mobileCard1 = new MobileCard(phone1,"小王",phone1,new SuperPackage(),
                78,22,200,50,1024);
        MobileCard mobileCard2 = new MobileCard(phone2,"小秦",phone2,new TalkPackage(),
                58,62,500,30,0);
        MobileCard mobileCard3 = new MobileCard(phone3,"小红",phone3,new NetPackage(),
                68,55,0,0,3*1024);
        list.add(new ConsumInfo("13978978956","超人套餐",78));
        map2.put("13978978956",list);
        list2.add(new ConsumInfo("13954697751","话痨套餐",58));
        map2.put("13954697751",list2);
        list3.add(new ConsumInfo("13955687997","网虫套餐",68));
        map2.put("13955687997",list3);
        cards.put(phone1,mobileCard1);
        cards.put(phone2,mobileCard2);
        cards.put(phone3,mobileCard3);
    }
    public static void login(){
        System.out.println("***************************登录***************************");
        if (CardUtil.nowPhone != null) {
            System.out.println("请输入是否使用缓存y/n");
            String choice = sc.next();
            if (choice.equals("n")) {
                login2();
            } else if(choice.equals("y")){
                Start.two();
            }else {
                System.out.println("输入错误,返回主菜单");
            }
        } else {
            login2();
        }
    }

    public static void login2(){
        System.out.println("请输入用户卡号:");
        String phone = sc.next();
        System.out.println("请输入密码:");
        String password = sc.next();
        for (Map.Entry<String, MobileCard> entry : cards.entrySet()) {
            if (entry.getKey().equals(phone) && entry.getValue().getPassWord().equals(password)) {
                nowPhone = phone;
                nowPassword = password;
                mobileCard = entry.getValue();
                System.out.println("手机号" + phone + ":登录成功！！！");
                if(Start.flag) {
                    Start.two();
                    return;
                }else {
                    return;
                }
            }
        }
        if(nowPhone==null) {
            System.out.println("账号或密码错误！！！");
        }
    }

    public static void registered(){
        try {
            int n = 0;
            String[] phones = new String[9];
            System.out.println("***************************注册***************************");
            Random r = new Random();
            one:
            while (n < 9) {
                String sum = 139+String.valueOf(r.nextInt(89999999)+10000000);
                for (Map.Entry<String, MobileCard> entry : cards.entrySet()) {
                    if (entry.getKey().equals(sum)) {
                        break one;
                    }
                }
                phones[n] = sum;
                n++;
            }
            System.out.print("************************可选择的卡号************************");
            for (int i = 0; i < 9; i++) {
                if (i % 3 == 0) System.out.println();
                System.out.print((i + 1) + "." + phones[i] + "\t");
            }
            System.out.println();
            System.out.print("请选择卡号(输入1-9的序号):");
            String choice = sc.next();
            int ce1 =Integer.parseInt(choice);
            while ( ce1< 1 || ce1 > 9) {
                System.out.print("序号错误，请重新选择:");
                choice = sc.next();
                ce1 =Integer.parseInt(choice);
            }
            System.out.print("1.话痨套餐  2.网虫套餐  3.超人套餐,  请选择套餐(输入序号):");
            String choice2 = sc.next().charAt(0)+"";
            int ce2 = Integer.parseInt(choice2);
            while (!( ce2== 1 || ce2 == 2|| ce2 == 3)) {
                System.out.print("请重新输入:");
                choice2 = sc.next();
                ce2 =Integer.parseInt(choice2);
            }
            ServicePackage sp = null;
            if (choice2.equals("1")) {
                sp = new TalkPackage();
            }else if(choice2.equals("2")){
                sp = new NetPackage();
            }else{
                sp = new SuperPackage();
            }
            tariffDescription(Integer.parseInt(choice2));
            System.out.print("请输入姓名:");
            String name = sc.next();
            System.out.print("请输入密码:");
            String password = sc.next();
            System.out.print("请输入预存话费金额:");
            double money = sc.nextDouble();
            int money1 = ce2 == 1 ? 58 : ce2 == 2 ? 68 : 78;
            int realTalkTime = ce2 ==1 ?  500 :ce2 == 2 ? 0 : 200;
            int realFlow = ce2 ==1 ?  0 :ce2 == 2 ? 3*1024 : 1024;
            int realSMSCount = ce2 ==1 ?  30 :ce2 == 2 ? 0 : 50;
            while (money < money1) {
                System.out.print("您预存的话费金额不足以支付本月套餐，请重新充值:");
                money = sc.nextDouble();
            }
            MobileCard mobileCard = new MobileCard(phones[ce1-1],name,password,sp,
                    money1,money-money1,realTalkTime,realSMSCount,realFlow);
            cards.put(phones[ce1-1],mobileCard);
            List<ConsumInfo> list = new ArrayList<>();
            String type = ce2 ==1 ?  "超人套餐" :ce2 == 2 ? "网虫套餐" : "话痨套餐";
            ConsumInfo ci = new ConsumInfo(phones[ce1-1],type,money1);
            list.add(ci);
            map2.put(phones[ce1-1],list);
            System.out.println("注册成功！！！");
            serialization();
        }catch (InputMismatchException e){
            System.out.println("您输入了其他错误的字符,请重试:1,或者返回上一级:输入任意字符");
            sc.next();
            String choice = sc.next();
            if (choice.equals("1")) {
                registered();
            }
        }
    }

    public static void use5G() {
        try {
            System.out.println("正在使用兜兜5G");
            while (cards.get(nowPhone).getMoney() <= 0) {
                System.out.println("余额不足,去充值实现本功能！！！");
                rechargePhBi();
            }
            MobileCard mc = cards.get(nowPhone);
            List<ConsumInfo> list = map2.getOrDefault(nowPhone, new ArrayList<>());
            Random r = new Random();
            int n = r.nextInt(6);
            int flow,time,sms;
            switch (n) {
                case 0:
                    System.out.println("您正在打电话联系客户");
                    time = r.nextInt(88) + 3;
                    System.out.println("本次使用电话:" + "您打了" + time + "min");
                    csi.call(time, mc);
                    list.add(new ConsumInfo(nowPhone, "通话", time));
                    break;
                case 1:
                    System.out.println("您正在打电话和朋友一边聊天,一边打游戏");
                    time = r.nextInt(88) + 3;
                    flow = r.nextInt(300) + 200;
                    System.out.println("本次使用电话---" + "共计" + time + "min");
                    System.out.println("本次使用流量---" + "共计" + flow + "MB");
                    csi.call(time, mc);
                    nsi.netPlay(flow, mc);
                    list.add(new ConsumInfo(nowPhone, "通话", time));
                    list.add(new ConsumInfo(nowPhone, "上网", flow));
                    break;
                case 2:
                    System.out.println("您正在使用浏览器看视频");
                    flow = r.nextInt(500) + 1000;
                    System.out.println("本次使用流量---" + "共计" + flow + "MB");
                    nsi.netPlay(flow, mc);
                    list.add(new ConsumInfo(nowPhone, "上网", flow));
                    break;
                case 3:
                    System.out.println("您正在向朋友发送短信聊天");
                    sms = r.nextInt(20) + 10;
                    System.out.println("本次使用短信---" + "共计" + sms + "条");
                    ssi.send(sms, mc);
                    list.add(new ConsumInfo(nowPhone, "短信", sms));
                    break;
                case 4:
                    System.out.println("您正在向每位同事发送短信通知");
                    sms = r.nextInt(16) + 35;
                    System.out.println("本次使用短信---" + "共计" + sms + "条");
                    ssi.send(sms, mc);
                    list.add(new ConsumInfo(nowPhone, "短信", sms));
                    break;
                case 5:
                    System.out.println("您正在使用网盘下载文件");
                    flow = r.nextInt(800) + 2000;
                    System.out.println("本次使用流量---" + "共计" + flow + "MB");
                    nsi.netPlay(flow, mc);
                    list.add(new ConsumInfo(nowPhone, "上网", flow));
                    break;
            }
            map2.put(nowPhone, list);
            serialization();
            System.out.println("继续使用兜兜5G:1,返回上一级:其他");
            String choice = sc.next();
            if (choice.equals("1")) {
                use5G();
            }
        } catch (InputMismatchException e) {
            System.out.println("输入了错误的字符,正在返回上一级");
        }
    }


    public static void rechargePhBi(){
        try {
            System.out.println("*************************话费充值*************************");
            System.out.print("请输入充值话费金额:");
            double money = sc.nextDouble();
            mobileCard.setMoney(mobileCard.getMoney() + money);
            cards.put(nowPhone, mobileCard);
            System.out.println("充值成功");
            serialization();
        }catch (IllegalArgumentException e){
            sc.next();
            System.out.println("您输入了其他错误的字符,请重试:1,或者返回上一级:输入任意字符");
            String choice = sc.next();
            if (choice.equals("1")) {
                rechargePhBi();
            }
        }
    }

    public static void tariffDescription(int n){
        ServicePackage sp = null;
        switch (n) {
            case 1:sp = new TalkPackage();break;
            case 2:sp = new NetPackage();break;
            case 3:sp = new SuperPackage();break;
            case 4:
                for(int i = 1;i<=3;i++){
                    tariffDescription(i);
                }break;
        }
        if(n==4){
            System.out.println("超出套餐资费:");
            System.out.println("通话---0.2元/分钟");
            System.out.println("短信---0.1元/条");
            System.out.println("上网---0.1元/MB");
        }
        if (sp != null) {
            sp.showInfo();
        }
    }

    public static void inTsMonBill(){
        System.out.println("************************本月账单查询************************");
        int money = 0;
        int money1 = cards.get(nowPhone).getMoneyDifference();
        List<ConsumInfo> list = map2.get(nowPhone);
        System.out.println("用户名:"+nowPhone);
        for (ConsumInfo ci : list) {
            if (ci.getType().equals("超人套餐") || ci.getType().equals("网虫套餐") || ci.getType().equals("话痨套餐")) {
                money = money + ci.getConsumData();
            }
        }
        System.out.println("套餐资费:" + money+"元");
        System.out.println("总计:" + (money + money1)+"元");
        System.out.println("账户余额:" + (int) cards.get(nowPhone).getMoney()+"元");
    }

    public static void queryBaPackage(){
        System.out.println("************************套餐余额查询************************");
        System.out.println("剩余套餐---");
        System.out.println("通话:"+cards.get(nowPhone).getRealTalkTime()+"min");
        System.out.println("流量:"+cards.get(nowPhone).getRealFlow()+"MB");
        System.out.println("短信:"+cards.get(nowPhone).getRealSMSCount()+"条");
    }

    public static void printConDetails(){
        File f = new File("D:\\c\\consumptionDetails.txt");
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter(f));
        String str = "************************打印消费详单************************\n";
        System.out.print(str);
        bw.write(str);
        int n = 0;
        str = "用户:" + nowPhone + "\t消费详单---\n";
        System.out.print(str);
        bw.write(str);
        str = String.format("%-8s%-11s%-30s%n", "序号", "类型", "数据(通话(条)/上网(MB)/短信(条)/金额(元))");
        System.out.printf(str);
        bw.write(str);
        List<ConsumInfo> list = map2.get(nowPhone);
        for (ConsumInfo ci : list) {
            n++;
            str = String.format("%-8s%-12s%-30s%n", n, ci.getType(), ci.getConsumData());
            System.out.printf(str);
            bw.write(str);
        }
        bw.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void packageChanges() {
        System.out.println("*************************变更套餐*************************");
        System.out.println("*************************资费说明*************************");
        tariffDescription(4);
        MobileCard mc = cards.get(nowPhone);
        int choice2;
        try {
            do {
                System.out.print("1.话痨套餐  2.网虫套餐  3.超人套餐, 请选择套餐(输入序号):");
                choice2 = sc.nextInt();
                if (choice2 < 1 || choice2 > 3) {
                    System.out.println("输入无效，请重新输入 1、2 或 3");
                } else if (mc.getSerPackage().price == (choice2 == 1 ? 58 : choice2 == 2 ? 68 : 78)) {
                    System.out.println("对不起,您已经是该套餐用户");
                }
            } while (choice2 < 1 || choice2 > 3 || mc.getSerPackage().price == (choice2 == 1 ? 58 : choice2 == 2 ? 68 : 78));
            ServicePackage sp = null;
            switch (choice2) {
                case 1:
                    sp = new TalkPackage();
                    mc.setRealTalkTime(TalkPackage.talkTime);
                    mc.setRealSMSCount(TalkPackage.amsCount);
                    mc.setRealFlow(0);
                    break;
                case 2:
                    sp = new NetPackage();
                    mc.setRealFlow(NetPackage.flow);
                    mc.setRealSMSCount(0);
                    mc.setRealTalkTime(0);
                    break;
                case 3:
                    sp = new SuperPackage();
                    mc.setRealFlow(SuperPackage.flow);
                    mc.setRealSMSCount(SuperPackage.smsCount);
                    mc.setRealTalkTime(SuperPackage.talkTime);
                    break;
            }
            mc.setSerPackage(sp);
            if (mc.getMoney() < sp.price) {
                System.out.println("余额不足，请充值");
                rechargePhBi();
            }
            mc.setMoney(mc.getMoney() - sp.price);
            mc.setMoneyDifference((int) (mc.getMoneyDifference() + sp.price));
            cards.put(nowPhone, mc);
            serialization();
            System.out.println("更改成功！！！");
        }catch (IllegalArgumentException e){
            sc.next();
            System.out.println("包含错误的字符请重新尝试:1,或返回主菜单");
            String choice = sc.next();
            if(choice.equals("1")){
                packageChanges();
            }
        }
    }

    public static void WithdrawalNetwork(){
        System.out.println("***************************办理退网***************************");
        cards.remove(nowPhone);
        if(map2.containsKey(nowPhone)){
            cards.remove(nowPhone);
            map2.remove(nowPhone);
            serialization();
            System.out.println("用户"+nowPhone+"退网成功!");
            System.out.println("谢谢使用!");
            nowPhone = null;
            Start.one();
        }
        System.out.println("不存在该账号！！！");
    }

    public static void displayInformation() {
        System.out.println("***************************显示用户信息***************************");
        System.out.println("手机号:" + cards.get(nowPhone).getCardNumber());
        System.out.println("用户名:" + cards.get(nowPhone).getUserName());
        System.out.println("密码:" + cards.get(nowPhone).getPassWord());
        System.out.print("话费包:");
        cards.get(nowPhone).getSerPackage().showInfo();
        System.out.println("手机余额:" + cards.get(nowPhone).getMoney()+"元");
        System.out.println("剩余通话时长:"+cards.get(nowPhone).getRealTalkTime()+"min");
        System.out.println("剩余短信条数:"+cards.get(nowPhone).getRealSMSCount()+"条");
        System.out.println("剩余流量:"+cards.get(nowPhone).getRealFlow()+"MB");
    }

    public static void serialization(){
        try {
            File f1 = new File("D:\\c\\userTable.txt");
            File f2 = new File("D:\\c\\consumptionTable.txt");
            if (!f1.exists()) {
                if (!f1.getParentFile().exists()) {
                    f1.getParentFile().mkdirs();
                }
                f1.createNewFile();
            }
            if (!f2.exists()) {
                if (!f2.getParentFile().exists()) {
                    f2.getParentFile().mkdirs();
                }
                f2.createNewFile();
            }
            FileOutputStream fos1 = new FileOutputStream(f1);
            ObjectOutputStream oos1 = new ObjectOutputStream(fos1);
            FileOutputStream fos2 = new FileOutputStream(f2);
            ObjectOutputStream oos2 = new ObjectOutputStream(fos2);
            oos1.writeObject(cards);
            oos2.writeObject(map2);
            oos1.close();
            oos2.close();
        }catch (IOException e){
            System.out.println("文件序列化错误");
        }
    }

    public static void deserialization() {
        try {
            File f1 = new File("D:\\c\\userTable.txt");
            FileInputStream fos1 = new FileInputStream(f1);
            ObjectInputStream oos1 = new ObjectInputStream(fos1);
            File f2 = new File("D:\\c\\consumptionTable.txt");
            FileInputStream fos2 = new FileInputStream(f2);
            ObjectInputStream oos2 = new ObjectInputStream(fos2);
            cards = (Map<String, MobileCard>)oos1.readObject();
            map2 = (Map<String, List<ConsumInfo>>)oos2.readObject();
            oos1.close();
            oos2.close();
        }catch (IOException | ClassNotFoundException e){
            System.out.println("文件反序列化错误");
        }
    }
}

class CallServiceImpl implements CallService {
    @Override
    public void call(int minCount, MobileCard card) {
        if (card.getRealTalkTime() > minCount) {
            card.setRealTalkTime(card.getRealTalkTime() - minCount);
        } else {
            double cost = (minCount - card.getRealTalkTime()) * 0.2;
            card.setMoneyDifference((int) (cost + card.getMoneyDifference()));
            card.setMoney(card.getMoney() - cost);
            card.setRealTalkTime(0);
        }
    }
}

class NetServiceImpl implements NetService {
    @Override
    public void netPlay(int flow, MobileCard card) {
        if (card.getRealFlow() > flow) {
            card.setRealFlow(card.getRealFlow() - flow);
        } else {
            double cost = (flow - card.getRealFlow()) * 0.1;
            card.setMoneyDifference((int) (cost + card.getMoneyDifference()));
            card.setMoney(card.getMoney() - cost);
            card.setRealFlow(0);
        }
    }
}

class SendServiceImpl implements SendService {
    @Override
    public void send(int count, MobileCard card) {
        if (card.getRealSMSCount() > count) {
            card.setRealSMSCount(card.getRealSMSCount() - count);
        } else {
            double cost = (count - card.getRealSMSCount()) * 0.1;
            card.setMoneyDifference((int) (cost + card.getMoneyDifference()));
            card.setMoney(card.getMoney() - cost);
            card.setRealSMSCount(0);
        }
    }
}